package com.internetCafes.spms.web.job.task.sys;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.internetCafes.spms.web.customer.common.cont.CommonConst;
import com.internetCafes.spms.web.customer.common.cont.CustomerConst;
import com.internetCafes.spms.web.customer.common.cont.MsgConst;
import com.internetCafes.spms.web.customer.common.cont.RoleConst;
import com.internetCafes.spms.web.customer.entity.area.Area;
import com.internetCafes.spms.web.customer.entity.area.AreaManager;
import com.internetCafes.spms.web.customer.entity.customer.Customer;
import com.internetCafes.spms.web.customer.entity.customer.CustomerFlow;
import com.internetCafes.spms.web.customer.entity.msg.Msg;
import com.internetCafes.spms.web.customer.entity.user.EntUserInfo;
import com.internetCafes.spms.web.customer.model.customer.flow.CustomerFlowDo;
import com.internetCafes.spms.web.customer.model.customer.flow.CustomerFlowPo;
import com.internetCafes.spms.web.customer.model.user.EntUserInfoPo;
import com.internetCafes.spms.web.customer.model.user.UserDo;
import com.internetCafes.spms.web.customer.model.user.UserPo;
import com.internetCafes.spms.web.customer.service.area.IAreaManagerService;
import com.internetCafes.spms.web.customer.service.area.IAreaSaleService;
import com.internetCafes.spms.web.customer.service.area.IAreaService;
import com.internetCafes.spms.web.customer.service.customer.ICustomerFlowService;
import com.internetCafes.spms.web.customer.service.customer.ICustomerService;
import com.internetCafes.spms.web.customer.service.msg.IMsgService;
import com.internetCafes.spms.web.customer.service.user.IEntUserInfoService;
import com.sms.common.util.hutool.core.collection.CollectionUtil;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import com.sms.common.util.hutool.core.util.StrUtil;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.xml.crypto.Data;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 消息定时器
 */
@Component("entMsgTask")
public class EntMsgTask {

    @Autowired
    private IMsgService msgService;
    @Autowired
    private IAreaSaleService areaSaleService;
    @Autowired
    private IEntUserInfoService userInfoService;
    @Autowired
    private ICustomerFlowService flowService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private IAreaManagerService areaManagerService;
    @Autowired
    private IAreaService areaService;

    /**
     * 三十天内未跟进检测
     * 客户三十天内未跟进
     * 1-通知对应得管理人
     * 2-通知对应得跟进人
     */
    public void unFollowCheck() {
        List<Customer> customerList = customerService.unFollowCustomerList();
        if (CollectionUtil.isEmpty(customerList)) {
            return;
        }

        // 获取对应区域管理人
        List<Long> managerAreaIdList = new ArrayList<>();
        List<Long> cityIdList = customerList.stream().map(Customer::getCityId).collect(Collectors.toList());
        List<Long> areaIdList = customerList.stream().map(Customer::getAreaId).collect(Collectors.toList());
        managerAreaIdList.addAll(cityIdList);
        managerAreaIdList.addAll(areaIdList);
        CollectionUtil.distinct(managerAreaIdList);

        List<Long> tenantIdList = customerList.stream().map(Customer::getTenantId).collect(Collectors.toList());

        List<AreaManager> areaManagerList = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(managerAreaIdList)) {
            areaManagerList = areaManagerService.listNoTenantId(
                    new LambdaQueryWrapper<AreaManager>().in(AreaManager::getAreaId, managerAreaIdList)
                            .eq(AreaManager::getEffectiveFlag, CommonConst.FlagEnum.IS.getId()));
        }

        Map<Long, List<AreaManager>> managerByAreaId = new HashMap<>();

        if (CollectionUtil.isNotEmpty(areaManagerList)) {
            managerByAreaId = areaManagerList.stream().collect(Collectors.groupingBy(AreaManager::getAreaId));
        }

        // 获取跟进人信息
        List<Long> followUserIdList = customerList.stream().map(Customer::getFollowUserId).collect(Collectors.toList());
        List<UserPo> userPoList = userInfoService.userPoList(new UserDo().setIdList(followUserIdList));
        Map<Long, UserPo> followUserInfoMapById = userPoList.stream()
                .collect(Collectors.toMap(UserPo::getId, Function.identity()));

        // 获取企业管理人 -推送全部信息
        QueryWrapper<EntUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .in("tui.dept_id", tenantIdList)
                .and(eq -> eq.isNull("tri.type_id")
                        .or()
                        .eq("tri.type_id", RoleConst.RoleType.PLATFORM));
        List<EntUserInfoPo> tenantManagerList = userInfoService.poList(queryWrapper);
        Map<Long, List<EntUserInfoPo>> tenantManagerGroupByTenantId = tenantManagerList.stream()
                .collect(Collectors.groupingBy(EntUserInfoPo::getDeptId));

        String msgForManager;
        String msgForFollower;
        UserPo userPo;
        List<Msg> msgDoList = new ArrayList<>();
        Msg msg;
        Date now = new Date();
        List<Long> receiverIdList;
        for (Customer customer : customerList) {
            if (!followUserInfoMapById.containsKey(customer.getFollowUserId())) {
                continue;
            }
            receiverIdList = new ArrayList<>();
            userPo = followUserInfoMapById.get(customer.getFollowUserId());
            msgForManager = "跟进人\"" + (StrUtil.isNotBlank(userPo.getDeptName()) ? userPo.getDeptName() : "") + "-" + userPo.getNickName() + "\"超过30未跟进成交客户\"" + customer.getName() + "\"";
            // 获取跟进人
            msgForFollower = "\"超过30未跟进成交客户\"" + customer.getName() + "\"";
            msg = new Msg().setModuleCode(MsgConst.MODULE_CODE_CUSTOMER).setTypeId(MsgConst.Type.FOLLOW_OVER_TIME.getId()).setTenantId(customer.getTenantId())
                    .setContent(msgForFollower).setCreateBy(1L).setCreateByName("系统").setCreateTime(now).setReceiverIdList(Collections.singletonList(customer.getFollowUserId()));
            msgDoList.add(msg);

            // 管理层
            if (managerByAreaId.containsKey(customer.getAreaId())) {
                receiverIdList.addAll(managerByAreaId.get(customer.getAreaId()).stream().map(AreaManager::getManagerId).collect(Collectors.toList()));
            }
            if (managerByAreaId.containsKey(customer.getCityId())) {
                receiverIdList.addAll(managerByAreaId.get(customer.getCityId()).stream().map(AreaManager::getManagerId).collect(Collectors.toList()));
            }
            // 系统管理
            if (tenantManagerGroupByTenantId.containsKey(customer.getTenantId())) {
                receiverIdList.addAll(tenantManagerGroupByTenantId.get(customer.getTenantId()).stream().map(EntUserInfoPo::getId).collect(Collectors.toList()));
            }
            CollectionUtil.distinct(receiverIdList);
            msg = new Msg().setModuleCode(MsgConst.MODULE_CODE_CUSTOMER).setTypeId(MsgConst.Type.FOLLOW_OVER_TIME.getId()).setTenantId(customer.getTenantId())
                    .setContent(msgForManager).setCreateBy(1L).setCreateByName("系统").setCreateTime(now).setReceiverIdList(receiverIdList);
            msgDoList.add(msg);
        }
        if (CollectionUtil.isNotEmpty(msgDoList)) {
            // 保存信息
            msgService.saveBatchMsgNoSqlParser(msgDoList);
        }
    }

    /**
     * 每周统计跟进
     */
    public void weekCount() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        ThreadContext.bind(manager);
        // 获取上周流转记录
        List<CustomerFlowPo> flowList = flowService.poList(new CustomerFlowDo().setActionTag(CustomerConst.FlowPoListActionTag.WEEK_COUNT.getId()));
        Date now = new Date();
        if (CollectionUtil.isEmpty(flowList)) {
            return;
        }
        // 租户id列表
        List<Long> tenantIdList = flowList.stream().map(CustomerFlow::getTenantId).distinct().collect(Collectors.toList());

        // 流转先按企业租户分组 flowGroupByTenantId
        Map<Long, Map<Long, Map<Long, Map<Integer, List<CustomerFlowPo>>>>> flowGroupByActionTagAndAreaIdAndCityIdAndTenantId = flowList.stream().collect(
                Collectors.groupingBy(CustomerFlowPo::getTenantId, Collectors.groupingBy(CustomerFlowPo::getCityId,
                                Collectors.groupingBy(CustomerFlowPo::getAreaId, Collectors.groupingBy(CustomerFlowPo::getActionTag)))));

        // 获取对应区域管理人
        List<Long> managerAreaIdList = new ArrayList<>();
        List<Long> cityIdList = flowList.stream().map(CustomerFlowPo::getCityId).collect(Collectors.toList());
        List<Long> areaIdList = flowList.stream().map(CustomerFlowPo::getAreaId).collect(Collectors.toList());
        managerAreaIdList.addAll(cityIdList);
        managerAreaIdList.addAll(areaIdList);
        CollectionUtil.distinct(managerAreaIdList);

        List<AreaManager> areaManagerList = new ArrayList<>();
        List<Area> areaList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(managerAreaIdList)) {
            areaManagerList = areaManagerService.listNoTenantId(
                    new LambdaQueryWrapper<AreaManager>().in(AreaManager::getAreaId, managerAreaIdList)
                            .eq(AreaManager::getEffectiveFlag, CommonConst.FlagEnum.IS.getId()));
            // 获取区域信息
            areaList =
                    areaService.listNoTenantId(new LambdaQueryWrapper<Area>().in(Area::getId, managerAreaIdList));
        }
        Map<Long, Area> areaMapById = areaList.stream()
                .collect(Collectors.toMap(Area::getId, Function.identity()));


        // 获取企业管理人 -推送全部信息
        QueryWrapper<EntUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .in("tui.dept_id", tenantIdList)
                .and(eq -> eq.isNull("tri.type_id")
                        .or()
                        .eq("tri.type_id", RoleConst.RoleType.PLATFORM));

        List<EntUserInfoPo> tenantManagerList = userInfoService.poList(queryWrapper);
        Map<Long, List<EntUserInfoPo>> tenantManagerGroupByTenantId = tenantManagerList.stream()
                .collect(Collectors.groupingBy(EntUserInfoPo::getDeptId));

        Long tenantId;// 企业id
        List<Map<Long, Map<Long, Map<Integer, List<CustomerFlowPo>>>>> tenantFlowList; //企业操作记录
        Map<Integer, List<CustomerFlow>> tenantFlowByActionTag;// 企业操作记录根据操作类型分组
        List<Customer> tenantCustomerList;// 企业客户列表
        Long cityId; // 城市id
        String cityName; // 城市名称
        Long areaId; // 区域id
        String areaName; // 区域名称
        Map<Long, Map<Long, Map<Integer, List<CustomerFlowPo>>>> flowGroupByActionTagAndAreaIdAndCityId; // 客户信息通过区域id/城市id进行区分
        Map<Long, Map<Integer, List<CustomerFlowPo>>> flowGroupByActionTagAndAreaId; // 客户信息通过城市id分组
        Map<Integer, List<CustomerFlowPo>> flowGroupByActionTag;
        Map<Long,Map<Long, Map<Long, String>>> areaMsgByActionTagAndAreaIdAndCityIdAndTenantId = new HashMap<>(); // 客户信息通过区域id，城市id分组
        Map<Long, Map<Long, String>> areaMsgByAreaIdAndCityId;
        Map<Long, String> areaMsgByAreaId = null;
        List<String> msgList;
        String msg;
        List<CustomerFlowPo> areaCustomerFlowList;
        Map<Long, List<String>> msgListGroupByTenantId = new HashMap<>();
        Map<Long, Map<Long, List<String>>> msgListGroupByCityIdAndTenantId = new HashMap<>();
        Map<Long, List<String>> msgListGroupByCityId;
        List<String> msgListOfCity;
        List<String> msgListOfTanant;
        Area area;
        // 遍历流转/操作日志
        for (Map.Entry<Long, Map<Long, Map<Long, Map<Integer, List<CustomerFlowPo>>>>> flowGroupByActionTagAndAreaIdAndCityIdEntry : flowGroupByActionTagAndAreaIdAndCityIdAndTenantId.entrySet()) {
            tenantId = flowGroupByActionTagAndAreaIdAndCityIdEntry.getKey();

            // 按区域进行划分统计
            flowGroupByActionTagAndAreaIdAndCityId = flowGroupByActionTagAndAreaIdAndCityIdEntry.getValue();

            areaMsgByAreaIdAndCityId = new HashMap<>();
            msgListGroupByCityId = new HashMap<>();
            msgListOfTanant = new ArrayList<>();
            // 遍历城市区域分组
            for (Map.Entry<Long, Map<Long, Map<Integer, List<CustomerFlowPo>>>> flowGroupByActionTagAndAreaIdEntry : flowGroupByActionTagAndAreaIdAndCityId.entrySet()) {
                cityId = flowGroupByActionTagAndAreaIdEntry.getKey();
                flowGroupByActionTagAndAreaId = flowGroupByActionTagAndAreaIdEntry.getValue();
                // 获取区域分组
                areaMsgByAreaId = new HashMap<>();
                msgListOfCity = new ArrayList<>();

                for (Map.Entry<Long, Map<Integer, List<CustomerFlowPo>>> flowGroupByActionTagEntry : flowGroupByActionTagAndAreaId.entrySet()) {
                    areaId = flowGroupByActionTagEntry.getKey();
                    flowGroupByActionTag = flowGroupByActionTagEntry.getValue();
                    msg = areaMsg(flowGroupByActionTag);
                    areaMsgByAreaId.put(areaId, msg);
                    area = areaMapById.get(areaId);
                    msgListOfCity.add(area.getName() + "-" + msg);
                }
                areaMsgByAreaIdAndCityId.put(cityId, areaMsgByAreaId);
                msgListGroupByCityId.put(cityId, msgListOfCity);

                area = areaMapById.get(cityId);
                msgListOfTanant.add(area.getName() + ":" + CollectionUtil.join(msgListOfCity, ";"));
            }
            areaMsgByActionTagAndAreaIdAndCityIdAndTenantId.put(tenantId, areaMsgByAreaIdAndCityId);
            msgListGroupByCityIdAndTenantId.put(tenantId, msgListGroupByCityId);
            msgListGroupByTenantId.put(tenantId, msgListOfTanant);
        }

        List<String> msgAll;
        List<Msg> msgDoList = new ArrayList<>();
        Msg msgDo;
        // 管理员通知
        if (CollectionUtil.isNotEmpty(tenantManagerGroupByTenantId)) {
            for (Map.Entry<Long, List<EntUserInfoPo>> tenantManagerEntry : tenantManagerGroupByTenantId.entrySet()) {
                tenantId = tenantManagerEntry.getKey();
                if (!msgListGroupByTenantId.containsKey(tenantId)) {
                    continue;
                }
                msg = CollectionUtil.join(msgListGroupByTenantId.get(tenantId), "|");
                msgDo = new Msg().setModuleCode(MsgConst.MODULE_CODE_CUSTOMER)
                        .setTypeId(MsgConst.Type.CUSTOMER_UPDATE.getId()).setTenantId(tenantId).setCreateTime(now)
                        .setContent(msg).setCreateBy(1L).setCreateByName("系统").setReceiverIdList(tenantManagerEntry.getValue().stream().map(EntUserInfoPo::getId).collect(Collectors.toList()));
                msgDoList.add(msgDo);
            }
        }
        // 管理层通知
        if (CollectionUtil.isNotEmpty(areaManagerList)) {
            Map<Long, Map<Long, Map<Long, Map<Long, List<AreaManager>>>>> areaListGroupByAreaIdAndCityIdAndManagerIdAndTenantId = areaManagerList.stream()
                    .collect(Collectors.groupingBy(AreaManager::getTenantId,
                            Collectors.groupingBy(AreaManager::getManagerId,
                                    Collectors.groupingBy(AreaManager::getCityId,
                                            Collectors.groupingBy(AreaManager::getAreaId)))));
            Map<Long, Map<Long, Map<Long, List<AreaManager>>>> areaListGroupByAreaIdAndCityIdAndManagerId;
            Map<Long, List<AreaManager>> areaListGroupByAreaId;
            Map<Long, Map<Long, List<AreaManager>>> areaListGroupByAreaIdAndCityId;
            Long receiverId;
            for (Map.Entry<Long, Map<Long, Map<Long, Map<Long, List<AreaManager>>>>> areaListGroupByAreaIdAndCityIdAndManagerIdEntry : areaListGroupByAreaIdAndCityIdAndManagerIdAndTenantId.entrySet()) {
                tenantId = areaListGroupByAreaIdAndCityIdAndManagerIdEntry.getKey();
                if (!msgListGroupByCityIdAndTenantId.containsKey(tenantId)) {
                    continue;
                }
                msgListGroupByCityId = msgListGroupByCityIdAndTenantId.get(tenantId);
                areaListGroupByAreaIdAndCityIdAndManagerId = areaListGroupByAreaIdAndCityIdAndManagerIdEntry.getValue();
                for (Map.Entry<Long, Map<Long, Map<Long, List<AreaManager>>>> areaListGroupByAreaIdAndCityIdEntry : areaListGroupByAreaIdAndCityIdAndManagerId.entrySet()) {
                    receiverId = areaListGroupByAreaIdAndCityIdEntry.getKey();
                    areaListGroupByAreaIdAndCityId = areaListGroupByAreaIdAndCityIdEntry.getValue();
                    for (Map.Entry<Long, Map<Long, List<AreaManager>>>  areaListGroupByAreaIdEntry : areaListGroupByAreaIdAndCityId.entrySet()) {
                        cityId = areaListGroupByAreaIdEntry.getKey();
                        areaListGroupByAreaId = areaListGroupByAreaIdEntry.getValue();
                        // 区域管理员
                        if (areaListGroupByAreaId.containsKey(cityId)) {
                            msgList = msgListGroupByCityId.get(cityId);
                        } else {
                            msgList = new ArrayList<>();
                            for (Map.Entry<Long, List<AreaManager>> areaListEntry : areaListGroupByAreaId.entrySet()) {
                                areaId = areaListEntry.getKey();
                                if (CollectionUtil.isNotEmpty(areaMsgByAreaId) && areaMsgByAreaId.containsKey(areaId)) {
                                    msgList.add(areaMsgByAreaId.get(areaId));
                                }
                            }
                        }
                        if (CollectionUtil.isNotEmpty(msgList)) {
                            msg = CollectionUtil.join(msgList, ";");
                            msgDo = new Msg().setModuleCode(MsgConst.MODULE_CODE_CUSTOMER)
                                    .setTypeId(MsgConst.Type.CUSTOMER_UPDATE.getId()).setTenantId(tenantId).setCreateTime(now)
                                    .setContent(msg).setCreateBy(1L).setCreateByName("系统").setReceiverIdList(Collections.singletonList(receiverId));
                            msgDoList.add(msgDo);
                        }
                    }
                }
            }


        }

        if (CollectionUtil.isNotEmpty(msgDoList)) {
            // 保存信息
            msgService.saveBatchMsgNoSqlParser(msgDoList);
        }
    }

    private String areaMsg(Map<Integer, List<CustomerFlowPo>> flowGroupByActionTag) {
        List<String> actionMsgList = new ArrayList<>();
        String action;
        for (Map.Entry<Integer, List<CustomerFlowPo>> flowGroupEntry: flowGroupByActionTag.entrySet()) {
            CustomerConst.FlowActionTag tag = CustomerConst.FlowActionTag.getTagById(flowGroupEntry.getKey());
            action = ObjectUtil.isNotNull(tag) ? tag.getTag() : "其他";
            actionMsgList.add(action + flowGroupEntry.getValue().size());
        }
        return CollectionUtil.join(actionMsgList, ",");
    }
}
